﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebCrawler.Model;
using WebCrawler.Service;

namespace WebCrawler.ViewModel
{
    public class WebCCTVViewModel : ViewModelBase
    {
        public WebCCTVViewModel()
        {
            initBaseData();
        }

        #region 属性
        // 基础URL
        public string Url
        {
            get { return _url; }
            set { _url = value; RaisePropertyChanged(() => Url); }
        }
        private string _url;

        // 全景图名
        public string Name
        {
            get { return _name; }
            set { _name = value; RaisePropertyChanged(() => Name); }
        }
        private string _name;

        // 是否下载单个的小图
        public bool DownloadSingleImage
        {
            get { return _downloadSingleImage; }
            set { _downloadSingleImage = value; RaisePropertyChanged(() => DownloadSingleImage); }
        }
        private bool _downloadSingleImage;

        // 使用数字作为6张图的命名
        public bool NumberSide
        {
            get { return _numberSide; }
            set { _numberSide = value; RaisePropertyChanged(() => NumberSide); }
        }
        private bool _numberSide;

        // 瓦片组合的行列数
        public int Tile
        {
            get { return _tile; }
            set { _tile = value; RaisePropertyChanged(() => Tile); }
        }
        private int _tile;

        public int Number1
        {
            get { return _number1; }
            set { _number1 = value; RaisePropertyChanged(() => Number1); }
        }
        private int _number1;

        public int Number2
        {
            get { return _number2; }
            set { _number2 = value; RaisePropertyChanged(() => Number2); }
        }
        private int _number2;

        public int Number3
        {
            get { return _number3; }
            set { _number3 = value; RaisePropertyChanged(() => Number3); }
        }
        private int _number3;

        // 占位符
        public ComplexInfoModel Placeholder
        {
            get { return _placeholder; }
            set { _placeholder = value; RaisePropertyChanged(() => Placeholder); }
        }
        private ComplexInfoModel _placeholder;

        // 占位符列表
        public List<ComplexInfoModel> PlaceholderList
        {
            get { return _placeholderList; }
            set { _placeholderList = value; RaisePropertyChanged(() => PlaceholderList); }
        }
        private List<ComplexInfoModel> _placeholderList;

        // 图片质量
        public ComplexInfoModel ImageQuality
        {
            get { return _imageQuality; }
            set { _imageQuality = value; RaisePropertyChanged(() => ImageQuality); }
        }
        private ComplexInfoModel _imageQuality;

        // 图片质量列表
        public List<ComplexInfoModel> ImageQualityList
        {
            get { return _imageQualityList; }
            set { _imageQualityList = value; RaisePropertyChanged(() => ImageQualityList); }
        }
        private List<ComplexInfoModel> _imageQualityList;

        public bool IsDownloading
        {
            get { return _isDownloading; }
            set { _isDownloading = value; RaisePropertyChanged(() => IsDownloading); }
        }
        private bool _isDownloading = false;

        public string StepMessage
        {
            get { return _stepMessage; }
            set { _stepMessage = value; RaisePropertyChanged(() => StepMessage); }
        }
        private string _stepMessage;
        #endregion

        private string _referer;

        #region 命令
        public RelayCommand StartDownloadCmd
        {
            get
            {
                if (_startDownloadCmd == null)
                    _startDownloadCmd = new RelayCommand(startDownload, canStartDownload);
                return _startDownloadCmd;
            }
            set { _startDownloadCmd = value; }
        }
        public RelayCommand _startDownloadCmd;
        #endregion

        #region 辅助函数
        private void initBaseData()
        {
            DownloadSingleImage = false;
            NumberSide = false;
            Tile = 4;

            PlaceholderList = new List<ComplexInfoModel>() {
              new ComplexInfoModel(){ Key="1",Text="0" },
              new ComplexInfoModel(){ Key="2",Text="00" },
              new ComplexInfoModel(){ Key="3",Text="000" }
            };
            Placeholder = PlaceholderList[0];

            //ImageQualityList = new List<ComplexInfoModel>() {
            //  new ComplexInfoModel(){ Key="0",Text="0" },
            //  new ComplexInfoModel(){ Key="1",Text="1" },
            //  new ComplexInfoModel(){ Key="2",Text="2" },
            //  new ComplexInfoModel(){ Key="3",Text="3" },
            //  new ComplexInfoModel(){ Key="4",Text="4" },
            //  new ComplexInfoModel(){ Key="5",Text="5" }
            //};
            ImageQualityList = new List<ComplexInfoModel>() {
              new ComplexInfoModel(){ Key="1",Text="l1" },
              new ComplexInfoModel(){ Key="2",Text="l2" },
              new ComplexInfoModel(){ Key="3",Text="l3" },
              new ComplexInfoModel(){ Key="4",Text="l4" },
              new ComplexInfoModel(){ Key="5",Text="l5" }
            };
            ImageQuality = ImageQualityList[0];

            // 测试
            //Url = "http://eyw.hnssdzzt.cn/720/indexdata/pano_1400";
            //Name = "鄂豫皖革命根据地";
            //Placeholder = PlaceholderList[0];
            //ImageQuality = ImageQualityList[2];
            //Tile = 4;
            //_referer = "https://720yun.com/";

            // http://ggkf40.cctv.com/vtour/panos/0-1-1.tiles/u/l2/1/l2_u_1_1.jpg
            // http://ggkf40.cctv.com/vtour/panos/{编号1}-{编号2}-{编号3}.tiles/{方向}/{质量}/{行}/{质量}_{方向}_{行}_{列}.jpg
            Url = "http://ggkf40.cctv.com/vtour/panos";
            Name = "庆祝改革开放40周年大型展览网上展馆";
            Number1 = 0;
            Number2 = 1;
            Number3 = 1;
            Placeholder = PlaceholderList[0];
            ImageQuality = ImageQualityList[1];
            Tile = 3;
            _referer = "http://ggkf40.cctv.com/vtour/tour.shtml";
        }

        private async void startDownload()
        {
            //string folderPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}/{Web720yun.Name}";
            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}/{Name}";

            StepMessage = "开始";
            IsDownloading = true;

            await download(Url, ImageQuality.Text, Tile, Placeholder.Text, folderPath, DownloadSingleImage);

            IsDownloading = false;
            StepMessage = "完成";
        }

        private bool canStartDownload()
        {
            return true;
        }

        private async Task download(string url, string quality, int tile, string placeholder, string folder, bool saveSingleImage)
        {
            string curTile = string.Empty;
            string curUrl = string.Empty;

            // 左上
            curTile = 1.ToString(placeholder);
            //curUrl = $"{url}/f/{0}/{8}_{0}.jpg";
            curUrl = $"{url}/{Number1}-{Number2}-{Number3}.tiles/f/{quality}/{curTile}/{quality}_f_{curTile}_{curTile}.jpg";
            StepMessage = $"计算左上角像素";
            Mat upperLeft = await ImageUtility.DownloadImageAsync(curUrl, "", false);

            // 右下
            curTile = tile.ToString(placeholder);
            //curUrl = $"{url}/f/{quality}/{curTile}/{quality}_f_{curTile}_{curTile}.jpg";
            curUrl = $"{url}/{Number1}-{Number2}-{Number3}.tiles/f/{quality}/{curTile}/{quality}_f_{curTile}_{curTile}.jpg";
            StepMessage = $"计算右下角像素";
            Mat lowerRight = await ImageUtility.DownloadImageAsync(curUrl, "", false);

            Dictionary<string, Mat> mats = new Dictionary<string, Mat>();
            // 请求单张图片
            for (int i = 0; i < 6; i++)
            {
                string side = string.Empty;

                if(NumberSide)
                {
                    side = i.ToString(placeholder);
                }
                else
                {
                    switch (i)
                    {
                        case 0: side = "f"; break;
                        case 1: side = "b"; break;
                        case 2: side = "r"; break;
                        case 3: side = "l"; break;
                        case 4: side = "u"; break;
                        case 5: side = "d"; break;
                    }
                }

                Mat[,] matpArray = new Mat[tile, tile];

                for (int j = 0; j < tile; j++)
                {
                    for (int k = 0; k < tile; k++)
                    {
                        string row = (j + 1).ToString(placeholder);
                        string col = (k + 1).ToString(placeholder);

                        //curUrl = $"{url}/{side}/{quality}/{j}_{k}.jpg";
                        curUrl = $"{url}/{Number1}-{Number2}-{Number3}.tiles/{side}/{quality}/{row}/{quality}_{side}_{row}_{col}.jpg";
                        string fileName = $"{folder}/single/{quality}_{side}_{row}_{col}.jpg";

                        StepMessage = $"下载：{curUrl}";
                        Mat mat = await ImageUtility.DownloadImageAsync(curUrl, fileName, saveSingleImage, _referer);

                        matpArray[j, k] = mat;
                    }
                }

                if (NumberSide)
                {
                    switch (i)
                    {
                        case 0: side = "f"; break;
                        case 1: side = "r"; break;
                        case 2: side = "b"; break;
                        case 3: side = "l"; break;
                        case 4: side = "u"; break;
                        case 5: side = "d"; break;
                    }
                }
                StepMessage = $"合并：{side}";
                Mat mat_Side = await ImageUtility.MergeSide(side, folder, matpArray, upperLeft.Size(), lowerRight.Size());
                mats[side] = mat_Side;
            }

            // 释放
            upperLeft.Dispose();
            lowerRight.Dispose();

            // 合并Cube
            StepMessage = $"合并：Cubemap";
            Mat cubemap = await ImageUtility.MergeCubemapAsync(folder, mats);

            // 转换全景图
            StepMessage = $"合并：Panorama";
            await ImageUtility.CubemapToPanoramaAsync(folder, cubemap);
        }
        #endregion
    }
}